package com.nineclock.sign.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.entity.PageResult;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.DateTimeUtil;
import com.nineclock.sign.dto.SignAllUserDTO;
import com.nineclock.sign.dto.SignDTO;
import com.nineclock.sign.dto.SignInfoDTO;
import com.nineclock.sign.dto.SignPCListDTO;
import com.nineclock.sign.mapper.SignInfoMapper;
import com.nineclock.sign.mapper.SignPictureMapper;
import com.nineclock.sign.pojo.SignInfo;
import com.nineclock.sign.service.SignInfoAttendanceService;
import com.nineclock.system.dto.SysCompanyUserDTO;
import com.nineclock.system.dto.SysDepartmentDTO;
import com.nineclock.system.feign.SysUserFeign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SignInfoAttendanceServiceImpl implements SignInfoAttendanceService {
    @Autowired
    SignInfoMapper signInfoMapper;
    @Autowired
    SysUserFeign sysUserFeign;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    SignPictureMapper signPictureMapper;

    @Override
    public List<SignAllUserDTO> pagingSignCurrentUserByMonth(String dateStr) {
        /**
         * 指定日期 ,当前 企业 ,所有员工 的签到数据
         * 考勤 组为的员工的  分步 和 打卡记录
         */
        if (dateStr == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        List<SignAllUserDTO> result = new ArrayList<>();


        LambdaQueryWrapper<SignInfo> signInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        signInfoLambdaQueryWrapper.eq(SignInfo::getCreateDate, dateStr);
        signInfoLambdaQueryWrapper.eq(SignInfo::getCompanyId, CurrentUserHolder.get().getCompanyId());

        // 查询 签到 的而所有人
        List<SignInfo> signInfoList = signInfoMapper.selectList(signInfoLambdaQueryWrapper);
        if (signInfoList != null) {

            //所有的签到 得人
            Set<Long> companyUserIdSet =
                    signInfoList.stream().map(
                            signInfo -> signInfo.getCompanyUserId()).collect(Collectors.toSet());

            //
            for (Long companyUserId : companyUserIdSet) {
                LambdaQueryWrapper<SignInfo> signInfoQW = new LambdaQueryWrapper<>();
                signInfoQW.eq(SignInfo::getCompanyId, CurrentUserHolder.get().getCompanyId())
                        .eq(SignInfo::getCompanyUserId, companyUserId)
                        .eq(SignInfo::getCreateDate, dateStr);
                //每个人 当天 的 签到 情况
                List<SignInfo> signInfos = signInfoMapper.selectList(signInfoQW);

                List<SignDTO> signDTOList = new ArrayList<>();
                SignAllUserDTO signAllUserDTO = new SignAllUserDTO();
                // 查找用户名
                for (SignInfo signInfo : signInfos) {
                    SignDTO signDTO = BeanHelper.copyProperties(signInfo, SignDTO.class);

                    //
                    SysCompanyUserDTO data = sysUserFeign.findCompanyUserId(signInfo.getCompanyUserId()).getData();
                    //封装返回值数据

                    signAllUserDTO.setUsername(data.getUserName());

                    signDTO.setUserName(data.getUserName());

                    //redis取当月签到次数
                    String key = DateTimeUtil.dateToStr(new Date(), DateTimeUtil.TIME_FORMAT_4) + data.getMobile();
                    String dayCount = (String) redisTemplate.boundValueOps(key).get();
                    signDTO.setMonthCount(dayCount);
                    //redis取当日签到次数
                    /*String key1 = DateTimeUtil.dateToStr(new Date(), DateTimeUtil.TIME_FORMAT_2) + data.getMobile();
                    String dayCount1 = (String) redisTemplate.boundValueOps(key1).get();*/
                    LambdaQueryWrapper<SignInfo> signInfoLambdaQueryWrapper1 = new LambdaQueryWrapper<>();
                    signInfoLambdaQueryWrapper1.eq(SignInfo::getCreateDate,signInfo.getCreateDate());
                    signInfoLambdaQueryWrapper1.eq(SignInfo::getCompanyUserId,signInfo.getCompanyUserId());
                    Integer count = signInfoMapper.selectCount(signInfoLambdaQueryWrapper1);
                    signDTO.setDayCount(String.valueOf(count));

                    signDTOList.add(signDTO);
                    //封装返回值对象

                }
                signAllUserDTO.setSignResponseList(signDTOList);
                result.add(signAllUserDTO);
            }

            return result;
        }
        return null;
    }

    @Override
    public SignDTO queryCompanyUserById(Integer id) {

        SignInfo signInfo = signInfoMapper.selectById(id);
        return BeanHelper.copyProperties(signInfo, SignDTO.class);
    }

    @Override
    public PageResult<SignPCListDTO> querySignUserList(String endTime, String page, String pageSize, String startTime) {

        if (endTime == null && page == null && pageSize == null && startTime == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //返回封装数据
        PageResult<SignPCListDTO> result =new PageResult();

        //从企业获取分页数据
        PageResult<SysCompanyUserDTO> data = sysUserFeign.queryPageResult(page, pageSize).getData();
        List<SysCompanyUserDTO> rows = data.getRows();

        List<SignPCListDTO> signPCListDTOS = new ArrayList<>();
        for (SysCompanyUserDTO sysCompanyUserDTO : rows) {
            SignPCListDTO signPCListDTO = new SignPCListDTO();
            signPCListDTO.setId(sysCompanyUserDTO.getUserId());
            signPCListDTO.setUsername(sysCompanyUserDTO.getUserName());
            signPCListDTO.setWorkNumber(sysCompanyUserDTO.getWorkNumber());
            signPCListDTO.setPost(sysCompanyUserDTO.getPost());
            signPCListDTO.setSigns(this.queryMember(startTime,endTime,sysCompanyUserDTO));
            SysDepartmentDTO sysDepartmentDTO = new SysDepartmentDTO();
            sysDepartmentDTO.setId(sysCompanyUserDTO.getDepartmentId());
            sysDepartmentDTO.setName(sysCompanyUserDTO.getDepartmentName());
            signPCListDTO.setDepartment(sysDepartmentDTO);

            signPCListDTOS.add(signPCListDTO);
        }

        result.setRows(signPCListDTOS);

        result.setTotalPage( data.getTotalPage());
        result.setTotal(data.getTotal());
        return result;
    }



    public List<SignInfoDTO> queryMember(String startTime, String endTime, SysCompanyUserDTO sysCompanyUserDTO) {
        //获取指定范围内的 日期列表
        List<Date> dateList = DateTimeUtil.getDatesBetweenTwoDate(startTime, endTime, "yyyy-MM-dd");
        //转换日期字符串列表
        List<String> dateStrList = dateList.stream().map(date -> {
            String dateStr = DateTimeUtil.dateToStr(date, "yyyy-MM-dd");
            return dateStr;
        }).collect(Collectors.toList());


        //转换为 考勤对象
        if (sysCompanyUserDTO!=null){
            return this.getSignInfo(CurrentUserHolder.get().getCompanyId(), sysCompanyUserDTO, dateStrList);
        }


        return new ArrayList<>();
    }

    private List<SignInfoDTO> getSignInfo(Long companyId, SysCompanyUserDTO sysCompanyUserDTO, List<String> dateStrList) {


            List<SignInfoDTO> signInfoDTOList = new ArrayList<>();
            for (String s : dateStrList) {

                LambdaQueryWrapper<SignInfo> signInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                signInfoLambdaQueryWrapper.eq(SignInfo::getCompanyId,companyId);
                signInfoLambdaQueryWrapper.eq(SignInfo::getCreateDate,s);
                signInfoLambdaQueryWrapper.eq(SignInfo::getCompanyUserId, sysCompanyUserDTO.getId());

                Integer count = signInfoMapper.selectCount(signInfoLambdaQueryWrapper);

                SignInfoDTO signInfoDTO = new SignInfoDTO();
                signInfoDTO.setSignDate(s);
                signInfoDTO.setSignCount(count);

                signInfoDTOList.add(signInfoDTO);
            }

        if (signInfoDTOList==null) {
            return new ArrayList<>();
        }

        return signInfoDTOList;
    }


}
